#!/usr/bin/perl

use strict;

package main;

use List::Util 'first';
use Getopt::Long;
use XML::Twig;
use Sys::Hostname;
use Lunmgr ':all';
use PerlUtil;

use constant DASHES => '------------------';

my %_cmds = (
    lspci => '/sbin/lspci',
    scli => '/usr/local/bin/scli',
);

my %_opts = (rack => 0);

GetOptions(\%_opts,
          "-rack",
          "-xml",
          "-help|h");


time_section( "Show JBODS", 
              sub { lm_jbods($_opts{rack}, $_opts{xml}) } 
            );

sub lm_jbods {
    my ($rack, $xmlopt) = @_;

    chomp (my @fccards = grep {/QLogic/} `$_cmds{lspci}`);

    if (@fccards == 0) {
        LogMsg("No FC storage found");
    }
    else {
        my @devices = &FindFCDisks;

        if ($xmlopt) {
           print "<?xml version=\"1.0\" ?>\n<lunmgr_conf>\n"
               . "  <rack number=\"$rack\">\n";
        }

        chmod (my $scliout = `$_cmds{scli} -t -x`);

        my $twig = XML::Twig->new();
        $twig->parse($scliout);

        # Each HBA port is an <HBA> element under the root
        for my $hba ($twig->root->children('HBA')) {
            # Children of the <HBA> element are <HBA> and <Target>
            for my $hbainfo ($hba->children()) {
               # <HBA> child
               if (uc($hbainfo->name()) eq "HBA") {
                    my $wwnn = $hbainfo->att('WWNN');
                    $wwnn =~ s/-//g; # Remove the dashes in the WWNN
   
                    my $wwpn = $hbainfo->att('WWPN');
                    $wwpn =~ s/-//g; # Remove the dashes in the WWPN
   
                    my $portnum = $hbainfo->att('Port');
   
                    # Write HBA port information to XML file
                    if ($xmlopt) {
                        printf "    <port number=\"%d\" wwnn=\"%s\""
                             . " wwpn=\"%s\" src=\"%s\">\n",
                            $portnum,
                            lc($wwnn),
                            lc($wwpn),
                            hostname();
                    }
                    else { 
                        printf "\n%s\n%-36.36s", 
                               "Fibre Channel HBA port $portnum", DASHES; 
                    }
                }
                # <Target> child
                else {
                    my $wwnn = lc $hbainfo->first_child('WWNN')->text();
                    $wwnn =~ s/-//g; # Remove the dashes in the WWNN
   
                    my $wwpn = lc $hbainfo->first_child('WWPN')->text();
                    $wwpn =~ s/-//g; # Remove the dashes in the WWPN

                    my $portid = $hbainfo->first_child('Info')->att('PortID');
   
                    # Write disk enclosure information to the XML file
                    if ($xmlopt) {
                       printf "      <disk_enclosure wwnn=\"%s\" wwpn=\"%s\""
                            . " port=\"%s\">\n",
                           $wwnn,
                           $wwpn,
                           $portid;
                    }
                    else { 
                        print "\n  + " . lc($wwpn) . " with port ID $portid\n"; 
                    }
   
                    # Get all the devices in this disk enclosure (match on WWPN)
                    my $device = first {$_->wwn eq $wwpn} @devices;
                    if ($device) {
                        # Write LUN information to the XML file
                        print $xmlopt ?
                             $device->ToJbodXML(' ' x 8) . "\n"
                           : $device->ToJbodStr . "\n";
                    }
   
                   print "      </disk_enclosure>\n" if ($xmlopt);
                }
            }

            print "    </port>\n" if ($xmlopt);
        }

        print "  </rack>\n</lunmgr_conf>\n" if ($xmlopt);
    }
}
